home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Information / Digests / CSMP Digest / volume 1 / csmp-v1-219.txt < prev    next >
Encoding:
Text File  |  1994-12-08  |  62.6 KB  |  1,614 lines  |  [TEXT/R*ch]

  1. C.S.M.P. Digest             Sun, 29 Nov 92       Volume 1 : Issue 219
  2.  
  3. Today's Topics:
  4.  
  5.     Memory Manager-safe Deferred Tasks - A Proposal
  6.     How to tell if App is in Background?
  7.     Newton Development
  8.     Watch out for QDError
  9.     MPW C++ 3.1, does it work with MPW 3.2??
  10.     PBResolveFileIDRef() trouble
  11.     Help! CTB's NuLookup() call crashing...
  12.  
  13.  
  14.  
  15. The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
  16.  
  17. The digest is a collection of article threads from the internet newsgroup
  18. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  19. regularly and want an archive of the discussions.  If you don't know what a
  20. newsgroup is, you probably don't have access to it.  Ask your systems
  21. administrator(s) for details.  You can post articles to any newsgroup by
  22. mailing your article to newsgroup@ucbvax.berkeley.edu.  So, to post an
  23. article to comp.sys.mac.programmer, you mail it to
  24. comp-sys-mac-programmer@ucbvax.berkeley.edu.  Note the '-' instead of '.'
  25. in the newsgroup name.
  26.  
  27. Each issue of the digest contains one or more sets of articles (called
  28. threads), with each set corresponding to a 'discussion' of a particular
  29. subject.  The articles are not edited; all articles included in this digest
  30. are in their original posted form (as received by our news server at
  31. cs.uoregon.edu).  Article threads are not added to the digest until the last
  32. article added to the thread is at least one month old (this is to ensure that
  33. the thread is dead before adding it to the digest).  Article threads that
  34. consist of only one message are generally not included in the digest.
  35.  
  36. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
  37. [128.223.8.8] in the directory /pub/mac/csmp-digest.  Be sure to read the
  38. file /pub/mac/csmp-digest/README before downloading any files.  The most
  39. recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
  40. directory /info-mac/digest/csmp.  If you don't have ftp capability, the sumex
  41. archive has a mail server; send a message with the text '$MACarch help' (no
  42. quotes) to LISTSERV@ricevm1.rice.edu for more information.
  43.  
  44. The digest is also available via email.  Just send a note saying that you
  45. want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
  46. automatically receive each new issue as it is created.  Sorry, back issues
  47. are not available through the mailing list.
  48.  
  49. Send administrative mail to mkelly@cs.uoregon.edu.
  50.  
  51.  
  52. -------------------------------------------------------
  53.  
  54. From: mandel@tmc.tulane.edu (Jeff E Mandel)
  55. Subject: Memory Manager-safe Deferred Tasks - A Proposal
  56. Date: 12 Oct 92 15:37:01 GMT
  57. Organization: Tulane University School of Medicine
  58.  
  59. I was mulling over the recent thread on asynchronous MacTCP calls, and it
  60. finally became clear to me what it was I wanted as a "real-time mac
  61. programmer" - an oxymoron, to be sure.
  62.  
  63. Basically, I like the concept of the Deferred Task manager, but the only
  64. thing it really gets me is the ability to do something in a small number
  65. of milliseconds after an interrupt without making the cursor jump around
  66. and other interrupt-driven code halt in its tracks. What I really want is
  67. the ability to take the data I've gotten from the interrupting device and
  68. stuff it into a pointer or handle at the soonest opportunity. Thus, what
  69. I want is the ability to place a task in the DT queue, but flag it as
  70. "don't call me until you can give me access to the specified heap".
  71. Something like:
  72.  
  73. FUNCTION DTHzInstall (dtTaskPtr: QElemPtr, dtHeapZone: THz) : OSErr;
  74.  
  75. I looked in IM-VI (p28-30), and I noticed that there is a function
  76. DeferUserFn, which is designed to defer an interrupt routine which might
  77. cause a double page fault from occuring. What I want is different, but
  78. conceptually similar. I have this task which I want to run, but which
  79. isn't safe to run now, so Mr. Memory Manager, run it when next it can run.
  80.  
  81. Why does this help? Because currently, if I want to do anything that
  82. requires using the memory manager, I'm using a private event queue, and
  83. hoping that my application gets called often enough that my queue gets
  84. serviced before it starts overwriting itself. Normally, this is no
  85. problem, but what happens if I switch it to the background, and ask Word
  86. to repaginate my 50 page document? Or if the Appleshare Server dies, and
  87. Appleshare puts up a helpful Alert box to tell me this?
  88.  
  89. So my question is, would this meet people's needs? Are there other things
  90. that are needed in a deferred task, or can everything else be forestalled
  91. until the event loop? I'm not promising to implement this, or even to use
  92. someone else's scheme that does this; I just want to get discussion (as
  93. opposed to flames) going.
  94.  
  95. Jeff E Mandel MD MS
  96. Associate Professor of Anesthesiology
  97. Tulane University School of Medicine
  98. New Orleans, LA
  99.  
  100. mandel@tmc.tulane.edu
  101.  
  102. +++++++++++++++++++++++++++
  103.  
  104. From: wuertz@tik.ethz.ch (Andreas Wuertz)
  105. Date: 13 Oct 92 16:05:13 GMT
  106. Organization: Federal Institute of Technology
  107.  
  108. In article <1992Oct12.153701.19426@cs.tulane.edu> Jeff E Mandel,
  109. mandel@tmc.tulane.edu writes:
  110. >requires using the memory manager, I'm using a private event queue, and
  111. >hoping that my application gets called often enough that my queue gets
  112. >serviced before it starts overwriting itself. Normally, this is no
  113.  
  114. How about posting a HighLevel Event to your application?
  115. PostHighLevelEvent may be called during irq/dt as far as I know.
  116.  
  117. Andy (wuertz@tik.ethz.ch)
  118.  
  119. ========================================================================
  120. The only person who got all his work done by Friday was Robinson Crusoe.
  121. ========================================================================
  122.  
  123. +++++++++++++++++++++++++++
  124.  
  125. From: mandel@tmc.tulane.edu (Jeff E Mandel)
  126. Date: 13 Oct 92 19:57:07 GMT
  127. Organization: Tulane University School of Medicine
  128.  
  129. In article <1992Oct13.160513.21910@bernina.ethz.ch> Andreas Wuertz,
  130. wuertz@tik.ethz.ch writes:
  131. >How about posting a HighLevel Event to your application?
  132. >PostHighLevelEvent may be called during irq/dt as far as I know.
  133.  
  134. It doesn't solve the problem. There is no way the HLE can get serviced
  135. until I get back to the event loop, which could be milliseconds or hours,
  136. depending on the friendliness of the foreground app and/or user. In any
  137. event (heh, heh), once I'm in the event loop, it's no problem to do with
  138. my own private event queue.
  139.  
  140. +++++++++++++++++++++++++++
  141.  
  142. From: resnick@cogsci.uiuc.edu (Pete Resnick)
  143. Organization: University of Illinois at Urbana
  144. Date: Wed, 14 Oct 1992 04:44:55 GMT
  145.  
  146. Jeff E Mandel <mandel@tmc.tulane.edu> writes:
  147.  
  148. >Basically, I like the concept of the Deferred Task manager, but the only
  149. >thing it really gets me is the ability to do something in a small number
  150. >of milliseconds after an interrupt without making the cursor jump around
  151. >and other interrupt-driven code halt in its tracks. What I really want is
  152. >the ability to take the data I've gotten from the interrupting device and
  153. >stuff it into a pointer or handle at the soonest opportunity. Thus, what
  154. >I want is the ability to place a task in the DT queue, but flag it as
  155. >"don't call me until you can give me access to the specified heap".
  156.  
  157. I like this idea very much, and this would actually be pretty easy to
  158. implement: You could write a device driver that would simply call the
  159. routine you specified. You could call the device driver asynchronously,
  160. which can be done at interrupt time; the call will remain in the queue
  161. until interrupt time is over and the system gets to call the driver.
  162. Then the driver would call your task, which would be free to move
  163. memory. This should happen at least somewhat quicker than having to
  164. wait for your event loop to come around for the next time.
  165.  
  166. I do see one problem with the scheme:
  167.  
  168. >Something like:
  169.  
  170. >FUNCTION DTHzInstall (dtTaskPtr: QElemPtr, dtHeapZone: THz) : OSErr;
  171.  
  172. Note that the dtTaskPtr, or the parameter block in the case of my
  173. device driver idea, would have to be preallocated. You would still run
  174. into the same problem you have in your internal queue, that you may
  175. run out of space; in this case, you might run out of the queue
  176. elements you have allocated. But other than this, it would be no
  177. problem.
  178.  
  179. pr
  180. - -- 
  181. Pete Resnick             (...so what is a mojo, and why would one be rising?)
  182. Graduate assistant - Philosophy Department, Gregory Hall, UIUC
  183. System manager - Cognitive Science Group, Beckman Institute, UIUC
  184. Internet: resnick@cogsci.uiuc.edu
  185.  
  186. +++++++++++++++++++++++++++
  187.  
  188. From: Jeff E Mandel <mandel@tmc.tulane.edu>
  189. Organization: Tulane University School of Medicine
  190. Date: Wed, 14 Oct 1992 14:11:51 GMT
  191.  
  192. In article <Bw3H6x.IAo@news.cso.uiuc.edu> Pete Resnick,
  193. resnick@cogsci.uiuc.edu writes:
  194. >I like this idea very much, and this would actually be pretty easy to
  195. >implement: You could write a device driver that would simply call the
  196. >routine you specified. You could call the device driver asynchronously,
  197. >which can be done at interrupt time; the call will remain in the queue
  198. >until interrupt time is over and the system gets to call the driver.
  199. >Then the driver would call your task, which would be free to move
  200. >memory. This should happen at least somewhat quicker than having to
  201. >wait for your event loop to come around for the next time.
  202.  
  203. Well, I have done stuff like this in a driver, and you still have the
  204. same problem - someone has to call SystemTask for the driver to get
  205. called, and you can't always depend on it happening as often as you want.
  206.  
  207. >
  208. >I do see one problem with the scheme:
  209. >
  210. >>Something like:
  211. >
  212. >>FUNCTION DTHzInstall (dtTaskPtr: QElemPtr, dtHeapZone: THz) : OSErr;
  213. >
  214. >Note that the dtTaskPtr, or the parameter block in the case of my
  215. >device driver idea, would have to be preallocated. You would still run
  216. >into the same problem you have in your internal queue, that you may
  217. >run out of space; in this case, you might run out of the queue
  218. >elements you have allocated. But other than this, it would be no
  219. >problem.
  220.  
  221. There is no problem with preallocating enough dtTaskPtrs if you are
  222. guaranteed that the time that the dtTask is pending is small. When it is
  223. unbounded, then you need to make it BIG, which is why I strongly advocate
  224. the private queue. If you use a standard system queue, such as the event
  225. queue, you need to enlarge this queue's allocation at boot time, and it
  226. is memory permanently committed to this function.
  227.  
  228. Since people don't seem to be jumping in on this, here's my thinking on
  229. how to implement DTHzInstall.  It seems to me that the two problems to
  230. avoid are reentering a Memory Manager call that is non-reentrant, and
  231. attempting to move memory in a heap that is not "quiet". I'm pretty sure
  232. that satisfying the first criterion also satisfies the second, but if it
  233. doesn't, we can always solve that as well (why would you ever exit the
  234. Memory Manager with an inconsistent heap?)
  235.  
  236. The problem is that of a critical section. Unless there is some secret,
  237. undocumented semaphore for the Memory Manager, we create one of our own
  238. by a head/tail patch for every Memory Manager routine. Basically, the
  239. patch increments the semaphore on entry and decrements it on exit. Now,
  240. when our dtTask is delivered, and the semaphore is nonzero, the task is
  241. moved to a private queue, and the tail patch examines this queue, and
  242. when the semaphore decrements to zero, it executes every task there. This
  243. allows for the fact that one Memory Manager trap can invoke another. I'd
  244. probably set the current heap to the one passed in the dtHeapZone
  245. parameter and restore the previous one on exit.
  246.  
  247. The advantage of this approach is that you aren't messing with the memory
  248. manager to try to make it reentrant, you're just getting your task
  249. executed when the memory Manager isn't involved in managing memory. Sort
  250. of the difference between "Sh*t or get off the pot!" and "Please let me
  251. know when you're done, and if it's not too much trouble, leave me some
  252. paper" :-).
  253.  
  254. OK, having spread the kerosene on the floor, let me retreat to my bunker
  255. and wait for the flames to rise...
  256.  
  257. Jeff
  258.  
  259. +++++++++++++++++++++++++++
  260.  
  261. From: Mark.R.Valence@dartmouth.edu (Mark R. Valence)
  262. Date: 14 Oct 92 13:33:59 GMT
  263. Organization: Dartmouth College, Hanover, NH
  264.  
  265.  
  266. Jeff E Mandel <mandel@tmc.tulane.edu> writes:
  267. > [ suggestion for a Deferred Task Manager that allows memory movement. ]
  268.  
  269. In article <Bw3H6x.IAo@news.cso.uiuc.edu>
  270. resnick@cogsci.uiuc.edu (Pete Resnick) writes:
  271. > I like this idea very much, and this would actually be pretty easy to
  272. > implement: You could write a device driver that would simply call the
  273. > routine you specified. You could call the device driver asynchronously,
  274. > which can be done at interrupt time; the call will remain in the queue
  275. > until interrupt time is over and the system gets to call the driver.
  276. > Then the driver would call your task, which would be free to move
  277. > memory. This should happen at least somewhat quicker than having to
  278. > wait for your event loop to come around for the next time.
  279. > [ stuff deleted ]
  280. > Note that the dtTaskPtr, or the parameter block in the case of my
  281. > device driver idea, would have to be preallocated. You would still run
  282. > into the same problem you have in your internal queue, that you may
  283. > run out of space; in this case, you might run out of the queue
  284. > elements you have allocated. But other than this, it would be no
  285. > problem.
  286.  
  287. Well, just one more problem.  The device driver scheme suffers from the
  288. same limitations that the previously mentioned PostHighLevelEvent
  289. scheme does.  Time is only given to device drivers when nothing else is
  290. happening on earlier systems (6.0.x and previous).  The newer System 7
  291. gives drivers needTime on a more regular basis.
  292.  
  293. For example, when some application posts an alert in System 6, drivers
  294. do not get any time (dialog manager doesn't call SystemTask ??  I
  295. haven't explored.)  Also, if the mouse is held down in a menu, control,
  296. window title bar, etc. - same problem, no time for drivers.
  297.  
  298. The dialog problem goes away with System 7.  Menu, control, window
  299. problem is still there (I just re-confirmed that.  Boy, it's tough to
  300. keep an async connection when you are in the debugger!).
  301.  
  302. All this really means is that you can't depend on quick response.  This
  303. has the effect that your queue may overflow, with the implications
  304. mentioned by Pete Resnick.
  305.  
  306. There are some alternatives:
  307.  
  308. 1)  pre-allocate a buffer for a large queue.  Pray that the response
  309. will not be too bad.  After all, you only have to respond to a user. 
  310. If the user is scrolling through the News, or moving that game window
  311. aside, does he care if your window gets updated right this second?
  312.  
  313. 2)  in order to allow for a large queue, you have to pre-allocate a
  314. large buffer.  Well, if you are going to allocate all this space
  315. anyway, why not use the current Deferred Task mechanism, and just do
  316. your own memory management in this pre-allocated chunk of memory.
  317.  
  318. 3)  redesign your time-critical program to be interrupt-level.
  319.  
  320. It all depends on how quickly you need the event to be processed.
  321.  
  322.  
  323. Now back to the regularly scheduled discussions on the price of 7.1
  324.  
  325.  
  326. Mark.
  327.  
  328. +++++++++++++++++++++++++++
  329.  
  330. From: time@ice.com (Tim Endres)
  331. Date: Wed, 14 Oct 92 15:15:49 EST
  332. Organization: ICE Engineering, Inc.
  333.  
  334.  
  335. In article <Bw3H6x.IAo@news.cso.uiuc.edu> (comp.sys.mac.programmer), resnick@cogsci.uiuc.edu (Pete Resnick) writes:
  336. > Jeff E Mandel <mandel@tmc.tulane.edu> writes:
  337. > >Basically, I like the concept of the Deferred Task manager, but the only
  338. > >thing it really gets me is the ability to do something in a small number
  339. > >of milliseconds after an interrupt without making the cursor jump around
  340. > >and other interrupt-driven code halt in its tracks. What I really want is
  341. > >the ability to take the data I've gotten from the interrupting device and
  342. > >stuff it into a pointer or handle at the soonest opportunity. Thus, what
  343. > >I want is the ability to place a task in the DT queue, but flag it as
  344. > >"don't call me until you can give me access to the specified heap".
  345. > I like this idea very much, and this would actually be pretty easy to
  346. > implement: You could write a device driver that would simply call the
  347.  
  348. When we implemented MacTCP and MacNFS at citi.umich.edu, we were faced
  349. with countless interrupt level memory problems. As I remember, this was
  350. easily solved by creating and managing our own little heap for the
  351. things that we needed.
  352.  
  353.  
  354. tim endres - time@ice.com  -or- tbomb!time
  355. ICE Engineering, Inc - 8840 Main St, Whitmore Lake, MI 48189
  356. Phone (313) 449 8288 - FAX (313) 449-9208
  357. USENET - a slow moving self parody... ph
  358.  
  359. +++++++++++++++++++++++++++
  360.  
  361. From: Mark.R.Valence@dartmouth.edu (Mark R. Valence)
  362. Date: 14 Oct 92 22:04:13 GMT
  363. Organization: Dartmouth College, Hanover, NH
  364.  
  365. In article <1992Oct14.141151.5753@cs.tulane.edu>
  366. mandel@tmc.tulane.edu (Jeff E Mandel) writes:
  367.  
  368. > Since people don't seem to be jumping in on this, here's my thinking on
  369. > how to implement DTHzInstall.  It seems to me that the two problems to
  370. > avoid are reentering a Memory Manager call that is non-reentrant, and
  371. > attempting to move memory in a heap that is not "quiet". I'm pretty sure
  372. > that satisfying the first criterion also satisfies the second, but if it
  373. > doesn't, we can always solve that as well (why would you ever exit the
  374. > Memory Manager with an inconsistent heap?)
  375. > The problem is that of a critical section. Unless there is some secret,
  376. > undocumented semaphore for the Memory Manager, we create one of our own
  377. > by a head/tail patch for every Memory Manager routine. Basically, the
  378.  
  379.  
  380. Why not just patch NewHandle?  Then you can be guaranteed that it is
  381. safe to allocate memory, move the heap around, etc. because someone is
  382. already doing it.  You need a flag to make sure you don't re-enter your
  383. task scheduler, but that is easy.  What's more, you can implement the
  384. "Hz" functionality you originally wanted.  Here it is:
  385.  
  386. NewHandle patch (note that it is a head patch):
  387.  
  388.  if not alreadyExecuting then
  389.     alreadyExecuting = true
  390.     if SYS bit is set then
  391.        theheap = SysZone
  392.     else
  393.        theheap = TheZone
  394.  
  395.     scan the queued tasks, execute the
  396.     ones where dtHeapZone = theheap (or dtHeapZone = nil)
  397.  
  398.     alreadyExecuting = false
  399.  endif
  400.  JumpTo(realNewHandle)
  401.  
  402. end patch
  403.  
  404. Remember to save ALL registers!  One note on this declaration:
  405.  
  406. > FUNCTION DTHzInstall (dtTaskPtr: QElemPtr, dtHeapZone: THz) : OSErr;
  407.  
  408. Why not declare the following, which gives an "easier" function
  409. declaration:
  410.  
  411.  DTHzElemRec = record
  412.    qLink: Ptr;               { standard queue field }
  413.    qType: integer;           { standard queue field }
  414.    dthzReserved: LongInt;    { for future enhancements :-) }
  415.    dthzProc: ProcPtr;        { pointer to the proc to execute }
  416.    dthzZone: THz             { the zone that this elem likes, nil for
  417. all }
  418.  end;
  419.  
  420.  FUNCTION DTHzInstall (dthzTask: DTHzElemPtr): OSErr;
  421.  
  422. The problem with this implementation is that you don't know whether
  423. QuickDraw is in use, so you cannot draw to any ports.  But maybe all
  424. you want to do is allocate memory.  In general, you shouldn't use
  425. managers that are not re-entrant.  To use Quickdraw, you could
  426. similarly patch SetPort, and thereby make the executed tasks
  427. port-dependant.
  428.  
  429. Honey?  Do you smell smoke?
  430.  
  431. Mark.
  432.  
  433. +++++++++++++++++++++++++++
  434.  
  435. From: Jeff E Mandel <mandel@tmc.tulane.edu>
  436. Organization: Tulane University School of Medicine
  437. Date: Thu, 15 Oct 1992 14:14:37 GMT
  438.  
  439. In article <1992Oct14.220413.10732@dartvax.dartmouth.edu> Mark R.
  440. Valence, Mark.R.Valence@dartmouth.edu writes:
  441. >> The problem is that of a critical section. Unless there is some secret,
  442. >> undocumented semaphore for the Memory Manager, we create one of our own
  443. >> by a head/tail patch for every Memory Manager routine. Basically, the
  444. >
  445. >
  446. >Why not just patch NewHandle?  Then you can be guaranteed that it is
  447. >safe to allocate memory, move the heap around, etc. because someone is
  448. >already doing it.  You need a flag to make sure you don't re-enter your
  449. >task scheduler, but that is easy.  What's more, you can implement the
  450. >"Hz" functionality you originally wanted.  Here it is:
  451. >
  452. >NewHandle patch (note that it is a head patch):
  453. >
  454. > if not alreadyExecuting then
  455. >    alreadyExecuting = true
  456. >    if SYS bit is set then
  457. >       theheap = SysZone
  458. >    else
  459. >       theheap = TheZone
  460. >
  461. >    scan the queued tasks, execute the
  462. >    ones where dtHeapZone = theheap (or dtHeapZone = nil)
  463. >
  464. >    alreadyExecuting = false
  465. > endif
  466. > JumpTo(realNewHandle)
  467. >
  468. >end patch
  469. >
  470. >Remember to save ALL registers!
  471.  
  472. I believe this is not the best solution. There are many traps which move
  473. memory, and NewHandle is only one. To make this approach work, you'd have
  474. to head patch every trap which can move memory. Even if you wanted to do
  475. that much patching (Which is certainly feasible), you still have the
  476. problem that you are depending on someone to call one of the
  477. memory-moving traps before your deferred task is delivered. What if
  478. you're waiting for an IO request to complete? Or in a long computational
  479. loop? the deferred task is frozen out.
  480.  
  481. >One note on this declaration:
  482. >
  483. >> FUNCTION DTHzInstall (dtTaskPtr: QElemPtr, dtHeapZone: THz) : OSErr;
  484. >
  485. >Why not declare the following, which gives an "easier" function
  486. >declaration:
  487. >
  488. > DTHzElemRec = record
  489. >   qLink: Ptr;               { standard queue field }
  490. >   qType: integer;           { standard queue field }
  491. >   dthzReserved: LongInt;    { for future enhancements :-) }
  492. >   dthzProc: ProcPtr;        { pointer to the proc to execute }
  493. >   dthzZone: THz             { the zone that this elem likes, nil for
  494. >all }
  495. > end;
  496. >
  497. > FUNCTION DTHzInstall (dthzTask: DTHzElemPtr): OSErr;
  498.  
  499. Well, I did it that way so the dtTakPtr structure could be used. If you
  500. do it the way you suggest, then you should add a field for dtParm, so the
  501. user can pass in a pointer to globals or such. Really, however, I'd make
  502. the DTHzElemRec look like a DTElemRec with some extra fields, as
  503. DTHzInstall would just install a DTTask that invoked code to determiine
  504. whether the DTHzTask could be delivered immediately, or needed to be
  505. moved to the special queue to await the completion of the pending memory
  506. operations. Thus:
  507.  
  508.  DTHzElemRec = record
  509.    qLink: Ptr;               { standard queue field }
  510.    qType: integer;           { standard queue field }
  511.    dthzReserved: LongInt;    { for future enhancements :-) }
  512.    dthzProc: ProcPtr;        { filled in by  DTHzInstall}
  513.    dthzZone: THz             { the zone that this elem will utilize }
  514.    dthzTask: dtElemRec  { the DTTask }
  515.  end;
  516.  
  517. >
  518. >The problem with this implementation is that you don't know whether
  519. >QuickDraw is in use, so you cannot draw to any ports.  But maybe all
  520. >you want to do is allocate memory.  In general, you shouldn't use
  521. >managers that are not re-entrant.  To use Quickdraw, you could
  522. >similarly patch SetPort, and thereby make the executed tasks
  523. >port-dependant.
  524.  
  525. I believe that it is a bad idea to try to have too many things going on
  526. in "real-time". Drawing can be deferred until the app gets back to the
  527. event loop. The user can't deal with the new data in a background app
  528. when the foreground app is busy, so why worry about getting it to the
  529. screen? The only thing that can't wait is stuffing data from an external
  530. device into memory that won't be depleted under any foreseeable
  531. circumstance, and reinitiating the read operation. 
  532. >
  533. >Honey?  Do you smell smoke?
  534. I don't know, dear. But doesn't that door feel awfully warm?
  535.  
  536. Jeff
  537.  
  538. +++++++++++++++++++++++++++
  539.  
  540. From: mxmora@unix.SRI.COM (Matt Mora)
  541. Date: 15 Oct 92 16:13:47 GMT
  542. Organization: SRI International, Menlo Park, California
  543.  
  544. In article <1992Oct14.141151.5753@cs.tulane.edu> mandel@tmc.tulane.edu (Jeff E Mandel) writes:
  545.  
  546. >Well, I have done stuff like this in a driver, and you still have the
  547. >same problem - someone has to call SystemTask for the driver to get
  548. >called, and you can't always depend on it happening as often as you want.
  549.  
  550.  
  551. Set up a vbltask and call it every few ticks. Its not on any of the lists
  552. that says it moves memory or cannot be called at interupt time. :-)
  553.  
  554.  
  555.  
  556.  
  557.  
  558. Matt
  559. - -- 
  560. ___________________________________________________________
  561. Matthew Mora                |   my Mac  Matt_Mora@sri.com
  562. SRI International           |  my unix  mxmora@unix.sri.com
  563. ___________________________________________________________
  564.  
  565. +++++++++++++++++++++++++++
  566.  
  567. From: Mark.R.Valence@dartmouth.edu (Mark R. Valence)
  568. Date: 16 Oct 92 03:15:20 GMT
  569. Organization: Dartmouth College, Hanover, NH
  570.  
  571. I wrote:
  572. >Why not just patch NewHandle?  Then you can be guaranteed that it is
  573. >safe to allocate memory, move the heap around, etc. because someone is
  574. >already doing it.  You need a flag to make sure you don't re-enter your
  575. >task scheduler, but that is easy.  What's more, you can implement the
  576. >"Hz" functionality you originally wanted.  Here it is:
  577. >
  578.  
  579. In article <1992Oct15.141437.22887@cs.tulane.edu>
  580. mandel@tmc.tulane.edu (Jeff E Mandel) writes:
  581.  
  582. > I believe this is not the best solution. There are many traps which move
  583. > memory, and NewHandle is only one. To make this approach work, you'd have
  584. > to head patch every trap which can move memory. Even if you wanted to do
  585. > that much patching (Which is certainly feasible), you still have the
  586. > problem that you are depending on someone to call one of the
  587. > memory-moving traps before your deferred task is delivered. What if
  588. > you're waiting for an IO request to complete? Or in a long computational
  589. > loop? the deferred task is frozen out.
  590.  
  591.  
  592. No, you don't have to patch every trap that can move memory (jeez,
  593. that's quite a few!).  When ANYONE, including the routines in ROM,
  594. calls NewHandle, they are basically saying "I don't care if memory
  595. moves."  So, just patch NewHandle, and you have the necessary
  596. conditions for a DTHz Manager.  You are right that you would then be
  597. relying on someone else to call NewHandle, but that is going to be a
  598. drawback of any scheme.  Even if you trap every memory moving trap,
  599. what if my app is in the middle of its save loop (repeatedly calling
  600. _Write, which can't move memory).  Well, I guess you could check to see
  601. if it was an ASYNC write, and only do your DTHz stuff if the call was
  602. ASYNC.  Anyway, the point is that the NewHandle scheme will work pretty
  603. well (oh, go ahead and augment it with patches on NewPtr and
  604. NewTempHandle).  Remember that NewRgn, GetResource, etc. call
  605. NewHandle.
  606.  
  607. One test:  do an atb on NewHandle in MacsBug, and then try to get
  608. anything done.  Even pulling down a menu gets it (you have to move the
  609. mouse, though, so that some call is made that eventually gets down to
  610. calling NewHandle).  The hard one is moving a window.  I guess a trap
  611. on _DiffRgn will get the job done in this case.  Kind of ad hoc, but
  612. you aren't writing System software here (if you were you wouldn't have
  613. to worry about these hacks).
  614.  
  615. Here's a new idea:  replace the A-trap interrupt, have your handy
  616. "these traps move memory" table on hand, and then do the DTHz tasks
  617. when appropriate.  It would have to be done right (for speed), but it
  618. should work, after all you are in WAY before the OS, down to the bare
  619. bones CPU.  Neat-o.
  620.  
  621. > >Honey?  Do you smell smoke?
  622. > I don't know, dear. But doesn't that door feel awfully warm?
  623.  
  624. I've got the best asbestos suit available:  Long, specialized post that
  625. only you and I read, all others do the 'K' thing.
  626.  
  627. Mark.
  628.  
  629. +++++++++++++++++++++++++++
  630.  
  631. From: boyd@apple.com (scott boyd)
  632. Date: Wed, 21 Oct 1992 06:48:19 GMT
  633. Organization: Apple Computer Inc.
  634.  
  635. In article <1992Oct16.031520.5869@dartvax.dartmouth.edu>,
  636. Mark.R.Valence@dartmouth.edu (Mark R. Valence) wrote:
  637. [loads of bizarre stuff deleted]
  638.  
  639. Patching NewHandle to get yourself some safe-to-allocate time
  640. begs the question (and totally ignores what you might do to 
  641. performance of the overall system if you aren't careful).
  642.  
  643. Let's go back to basics.  What are you trying to accomplish?
  644. What is so important that it has to happen more often than
  645. driver tickle time?
  646.  
  647. scott
  648. boyd@apple.com
  649. macintosh system software
  650.  
  651. +++++++++++++++++++++++++++
  652.  
  653. From: mandel@tmc.tulane.edu (Jeff E Mandel)
  654. Date: 21 Oct 92 16:02:36 GMT
  655. Organization: Tulane University School of Medicine
  656.  
  657. In article <boyd-201092234525@kip2-53.apple.com> scott boyd,
  658. boyd@apple.com writes:
  659. >Patching NewHandle to get yourself some safe-to-allocate time
  660. >begs the question (and totally ignores what you might do to 
  661. >performance of the overall system if you aren't careful).
  662. >
  663. >Let's go back to basics.  What are you trying to accomplish?
  664. >What is so important that it has to happen more often than
  665. >driver tickle time?
  666.  
  667. Scott, as I started this, let me answer for Mark. Basically, the general
  668. class of problem we're discussing is interrupt-driven code, such as
  669. drivers, connection tools, etc. The idea was to create a new type of
  670. task, such as the Deferred Task, which would be delivered "soon", but be
  671. able to allocate memory, but not depend on the foreground app to be a
  672. good sport to function.
  673.  
  674. To my way of thinking, if I'm writing a driver which gathers data from an
  675. external device which won't stop sending just because the user has
  676. decided to mouse down in a menu, then I must have a mechanism for
  677. buffering data until my event-loop level code gets called again. I can
  678. allocate as much or as little as I want, but I have allocated that
  679. memory, and it is there whether I use it or not.
  680.  
  681. An alternate approach would be to queue a task to a memory-safe deferred
  682. task queue, which will be delivered the next time the Memory Manager
  683. isn't busy. Mark feels the easiest way is to service the queue whenever
  684. NewHandle is called, as that is prima facie evidence that the Memory
  685. Manager is open for new business. I have advocated patching the entire
  686. memory manager to maintain a guarding semaphore, and emptying the queue
  687. when the semaphore is zero (either because it is zero when the task is
  688. queued, or because our patched memory manager decrements it to zero). His
  689. scheme is probably less intrusive, mine guarantees faster delivery (the
  690. worst case being the time it takes to compact a swapped-out heap).
  691.  
  692. I know that this opens a big can of worms, but I believe that the benefit
  693. is that it permits the driver writer to simply queue an asynchronous read
  694. using memory from a small static pool for the ioBuffer, have a completion
  695. routine which queues the memory-safe deferred task, which copies the
  696. input data to a handle from temporary memory, and places the handle in a
  697. queue to be processed in the event loop. That way, the driver can buffer
  698. "indefinitely", even if the foreground app has hung and is waiting for
  699. the user to command-option-escape. You'll recall I've written real-time
  700. controllers which are used in the OR, and I have to be able to process
  701. new data every two seconds (come hell or high water), and the
  702. driver-tickle just isn't that reliable.
  703.  
  704. OK, so now tell me why it isn't possible, can be done with existing
  705. facilities, or is evil.
  706.  
  707. Jeff E Mandel MD MS
  708. Associate Professor of Anesthesiology
  709. Tulane University School of Medicine
  710. New Orleans, LA
  711.  
  712. mandel@vax.anes.tulane.edu
  713.  
  714. +++++++++++++++++++++++++++
  715.  
  716. From: resnick@cogsci.uiuc.edu (Pete Resnick)
  717. Date: 21 Oct 92 16:12:41 GMT
  718. Organization: University of Illinois at Urbana
  719.  
  720. boyd@apple.com (scott boyd) writes:
  721.  
  722. >Let's go back to basics.  What are you trying to accomplish?
  723. >What is so important that it has to happen more often than
  724. >driver tickle time?
  725.  
  726. Let's take the example I had in mind when I asked the original
  727. question: Let's say I wanted to implement a UNIX-like socket using
  728. MacTCP that could do a listen. The spec on listen is that it will
  729. listen to a certain TCP port and allow up to a user-specified number
  730. of connections. So, in MacTCP, that means TCPCreate a stream (about
  731. 16K of memory for the receive buffer) and put a TCPPassiveOpen on that
  732. stream. As soon as one connection is made, I need another stream and
  733. another passive open on the same TCP port. I can't do it in the
  734. completion routine of the PassiveOpen because I have to allocate the
  735. memory for the new stream buffer. I have two choices:
  736.  
  737. 1. Pre-allocate enough memory for every connection that could come in
  738. when the person calls listen(). Ick!
  739.  
  740. 2. Wait until I get back to my main event loop and allocate another
  741. block. There are certain applications where that time delay would be
  742. unacceptable.
  743.  
  744. Now, would the time delay for a device driver to come around and do it
  745. for me be unacceptable? Probably not. But just *probably*. If we had an
  746. AllocateMemASAP routine that we could call from interrupt, it would be
  747. alot nicer.
  748.  
  749. pr
  750. - -- 
  751. Pete Resnick             (...so what is a mojo, and why would one be rising?)
  752. Graduate assistant - Philosophy Department, Gregory Hall, UIUC
  753. System manager - Cognitive Science Group, Beckman Institute, UIUC
  754. Internet: resnick@cogsci.uiuc.edu
  755.  
  756. +++++++++++++++++++++++++++
  757.  
  758. From: bhamlin@netcom.com (Brian Hamlin)
  759. Date: 23 Oct 92 23:48:39 GMT
  760. Organization: Netcom - Online Communication Services  (408 241-9760 guest)
  761.  
  762. mxmora@unix.SRI.COM (Matt Mora) writes:
  763.  
  764. >In article <1992Oct14.141151.5753@cs.tulane.edu> mandel@tmc.tulane.edu (Jeff E Mandel) writes:
  765.  
  766. >>Well, I have done stuff like this in a driver, and you still have the
  767. >>same problem - someone has to call SystemTask for the driver to get
  768. >>called, and you can't always depend on it happening as often as you want.
  769.  
  770.  
  771. >Set up a vbltask and call it every few ticks. Its not on any of the lists
  772. >that says it moves memory or cannot be called at interupt time. :-)
  773.  
  774.   That's what AppleTalk does...
  775.  
  776.  
  777.  
  778. - --
  779. Brian M. Hamlin                          NOESIS Software Construction
  780. bhamlin@netcom.com                                     (510) 271-7971
  781.  
  782. - -- 
  783. - --
  784. Brian M. Hamlin                          NOESIS Software Construction
  785. bhamlin@netcom.com                                     (510) 271-7971
  786.  
  787. +++++++++++++++++++++++++++
  788.  
  789. From: mandel@tmc.tulane.edu (Jeff E Mandel)
  790. Date: 26 Oct 92 14:33:14 GMT
  791. Organization: Tulane University School of Medicine
  792.  
  793. In article <1992Oct23.234839.29677@netcom.com> Brian Hamlin,
  794. bhamlin@netcom.com writes:
  795. >>Set up a vbltask and call it every few ticks. Its not on any of the
  796. lists
  797. >>that says it moves memory or cannot be called at interupt time. :-)
  798. >
  799. >  That's what AppleTalk does...
  800.  
  801. This doesn't solve the problem, as you can't call the memory manager from
  802. a VBLTask either.
  803.  
  804. +++++++++++++++++++++++++++
  805.  
  806. From: minow@Apple.COM (Martin Minow)
  807. Date: 27 Oct 92 18:22:20 GMT
  808. Organization: Apple Computer Inc., Cupertino, CA
  809.  
  810.  
  811. boyd@apple.com (scott boyd) writes:
  812. >Let's go back to basics.  What are you trying to accomplish?
  813.  
  814. Much of this discussion reminds me of the aphorism: "if your only tool
  815. is a hammer, everything looks like a nail." As has been stated, the Mac
  816. Memory Manager is not re-entrant and cannot be called from interrupt
  817. routines.
  818.  
  819. The best solution for drivers and similar interrupt-driven code that
  820. must allocate memory dynamically will be, in my experience, based on
  821. a private, carefully written, interrupt-safe memory allocator that
  822. runs off of a private memory pool. Your driver will initialize the pool
  823. when it is opened for the first time. If you want to be exceedingly
  824. clever, you could probably write a background task that manages the
  825. pool size by using the Mac Memory Manager to allocate and deallocate
  826. chunks of memory in a "safe" manner. The intricacies of communicating
  827. between the driver and allocation task will be left as a exercise
  828. for the student.
  829.  
  830. Martin Minow
  831. minow@apple.com
  832.  
  833. +++++++++++++++++++++++++++
  834.  
  835. From: mandel@tmc.tulane.edu (Jeff E Mandel)
  836. Date: 27 Oct 92 20:04:28 GMT
  837. Organization: Tulane University School of Medicine
  838.  
  839. In article <73783@apple.Apple.COM> Martin Minow, minow@Apple.COM writes:
  840. >The best solution for drivers and similar interrupt-driven code that
  841. >must allocate memory dynamically will be, in my experience, based on
  842. >a private, carefully written, interrupt-safe memory allocator that
  843. >runs off of a private memory pool. Your driver will initialize the pool
  844. >when it is opened for the first time. If you want to be exceedingly
  845. >clever, you could probably write a background task that manages the
  846. >pool size by using the Mac Memory Manager to allocate and deallocate
  847. >chunks of memory in a "safe" manner. The intricacies of communicating
  848. >between the driver and allocation task will be left as a exercise
  849. >for the student.
  850.  
  851. First, I know I can manage my own interrupt-level heap, and can probably
  852. implement some sort of workspace trimming and expansion routine, but it
  853. is a lot of trouble, and commits memory resources inefficiently. What I
  854. need is not a way to manage a finite list of queue elements available for
  855. communication with the event loop, but rather, a way to buffer events for
  856. as long as possible if the event loop is frozen out, without having to
  857. dedicate excessive memory resources to the task. I know, memory is cheap,
  858. and everyone should have 20 megs so they can allocate a meg to a driver
  859. and not worry about it.
  860.  
  861. My solution (which I believe will work) to this is to create a task
  862. queue, which is serviced immediately if the Memory Manager isn't in the
  863. way, or as soon as it moves out of the way. From the application
  864. programmer's perspective, it's simple. In the ioCompletion routine, queue
  865. a task which takes the contents of the input buffer, and copy it to a
  866. handle, stuff the handle in a queue element, and let the event loop
  867. process the queue. If an ill-behaved program grabs the foreground for an
  868. hour, no problem, as long as there are memory resources to suuport it,
  869. you buffer and catch up when you get called again.
  870.  
  871. So, some specific questions:
  872.  
  873. 1) If I call NewHandle from an interrupt, and no Memory Manager call is
  874. being interrupted, do I cause any harm?
  875.  
  876. 2) On exit from a Memory Manager trap, is the heap ever inconsistent
  877. (other than as a result of an error)?
  878.  
  879. 3) Are there any traps, other than the documented traps of the Memory
  880. Manager, which move memory themselves (i.e. as a result of something
  881. other than a NewHandle call)?
  882.  
  883. I know that this idea hasn't exactly caught fire with the group, but I
  884. suspect it reflects the fact that very few people use the Deferred Task
  885. Manager. On the other hand, in the VMS world, it is very common to use
  886. ASTs, because there is a much shorter list of system services which you
  887. can't use from an AST.
  888.  
  889. If anyone is interested in the problem, and has some C/C++ code that
  890. patches anything in the memory manager from an extension/control panel,
  891. I'll see if I can program something up.
  892.  
  893. Jeff E Mandel MD MS
  894. Associate Professor of Anesthesiology
  895. Tulane University School of Medicine
  896. New Orleans, LA
  897.  
  898. mandel@vax.anes.tulane.edu
  899.  
  900. +++++++++++++++++++++++++++
  901.  
  902. From: resnick@cogsci.uiuc.edu (Pete Resnick)
  903. Date: 27 Oct 92 19:59:24 GMT
  904. Organization: University of Illinois at Urbana
  905.  
  906. minow@Apple.COM (Martin Minow) writes:
  907.  
  908. >boyd@apple.com (scott boyd) writes:
  909. >>Let's go back to basics.  What are you trying to accomplish?
  910.  
  911. >Much of this discussion reminds me of the aphorism: "if your only tool
  912. >is a hammer, everything looks like a nail." As has been stated, the Mac
  913. >Memory Manager is not re-entrant and cannot be called from interrupt
  914. >routines.
  915.  
  916. >The best solution for drivers and similar interrupt-driven code that
  917. >must allocate memory dynamically will be, in my experience, based on
  918. >a private, carefully written, interrupt-safe memory allocator that
  919. >runs off of a private memory pool.
  920.  
  921. Again, this misses the point. The problem is not that you can't
  922. allocate enough memory for all of your uses at initialization time and
  923. then use that; of course, that's easy. The *problem* is that you don't
  924. want to allocate a huge chunk of memory if you don't need it.
  925. Especially for things like drivers, sure I could allocate 1M right out
  926. of the system heap, and use it as my private memory pool, but that is
  927. exactly what I *don't* want to do when for the most part I will only
  928. be using 1K, but sometimes I might need some more. All this
  929. accomplishes is using up memory that other applications might very
  930. well need when I don't.
  931.  
  932. The perfect answer would be to let me allocate the memory I need at
  933. interrupt; we have all decided that this is not possible. What we have
  934. been looking for here is a compromise: allocate me the memory I need
  935. as soon as you can. The private memory pool just doesn't address this
  936. problem. If anything, that is exactly making "everything look like a
  937. nail."
  938.  
  939. pr
  940. - -- 
  941. Pete Resnick             (...so what is a mojo, and why would one be rising?)
  942. Graduate assistant - Philosophy Department, Gregory Hall, UIUC
  943. System manager - Cognitive Science Group, Beckman Institute, UIUC
  944. Internet: resnick@cogsci.uiuc.edu
  945.  
  946. +++++++++++++++++++++++++++
  947.  
  948. From: werner@soe.berkeley.edu (John Werner)
  949. Date: 27 Oct 92 20:42:44 GMT
  950. Organization: UC Berkeley School of Education
  951.  
  952. In article <1992Oct27.200428.14856@cs.tulane.edu>, Jeff E Mandel
  953.   <mandel@tmc.tulane.edu> wrote:
  954. > 1) If I call NewHandle from an interrupt, and no Memory Manager call is
  955. > being interrupted, do I cause any harm?
  956.  
  957. YES.  Some code (probably including many toolbox traps) may have
  958. dereferenced a handle into a pointer, and your NewHandle call might move
  959. the block out from under the pointer.  At interrupt time, it really isn't
  960. safe to do anything that might move memory.  Period.
  961.  
  962. > 3) Are there any traps, other than the documented traps of the Memory
  963. > Manager, which move memory themselves (i.e. as a result of something
  964. > other than a NewHandle call)?
  965.  
  966. Remember that MM traps other than NewHandle can move memory too.  NewPtr
  967. and MoveHHi come to mind immediately, but I'm sure there are others.
  968.  
  969. - --
  970. John Werner                         werner@soe.berkeley.edu
  971. UC Berkeley School of Education     510-642-9651
  972.  
  973. +++++++++++++++++++++++++++
  974.  
  975. From: absurd@apple.apple.com (Tim Dierks, software saboteur)
  976. Date: Tue, 27 Oct 1992 21:08:24 GMT
  977. Organization: MacDTS Marauders
  978.  
  979. In article <1992Oct27.200428.14856@cs.tulane.edu>, Jeff E Mandel
  980. <mandel@tmc.tulane.edu> wrote:
  981. > In article <73783@apple.Apple.COM> Martin Minow, minow@Apple.COM writes:
  982. > >The best solution for drivers and similar interrupt-driven code that
  983. > >must allocate memory dynamically will be, in my experience, based on
  984. > >a private, carefully written, interrupt-safe memory allocator that
  985. > >runs off of a private memory pool. Your driver will initialize the pool
  986. > >when it is opened for the first time. If you want to be exceedingly
  987. > >clever, you could probably write a background task that manages the
  988. > >pool size by using the Mac Memory Manager to allocate and deallocate
  989. > >chunks of memory in a "safe" manner. The intricacies of communicating
  990. > >between the driver and allocation task will be left as a exercise
  991. > >for the student.
  992. > My solution (which I believe will work) to this is to create a task
  993. > queue, which is serviced immediately if the Memory Manager isn't in the
  994. > way, or as soon as it moves out of the way. From the application
  995. > programmer's perspective, it's simple. In the ioCompletion routine, queue
  996. > a task which takes the contents of the input buffer, and copy it to a
  997. > handle, stuff the handle in a queue element, and let the event loop
  998. > process the queue. If an ill-behaved program grabs the foreground for an
  999. > hour, no problem, as long as there are memory resources to suuport it,
  1000. > you buffer and catch up when you get called again.
  1001. > So, some specific questions:
  1002. > 1) If I call NewHandle from an interrupt, and no Memory Manager call is
  1003. > being interrupted, do I cause any harm?
  1004. > 2) On exit from a Memory Manager trap, is the heap ever inconsistent
  1005. > (other than as a result of an error)?
  1006. > 3) Are there any traps, other than the documented traps of the Memory
  1007. > Manager, which move memory themselves (i.e. as a result of something
  1008. > other than a NewHandle call)?
  1009.  
  1010. Unfortunately, I don't see any way to make this work, except for perhaps
  1011. in a private heap, in which case using your own memory management is
  1012. probably a better solution.  The real sticking point is, as I see it,
  1013. that virtually all Mac programs and the toolbox rely on memory not
  1014. moving or being purged except at well-defined times.  Here's a perfectly
  1015. innocuous piece of code:
  1016.  
  1017.     baseAddress = (**myPixMap).baseAddr;
  1018.  
  1019. And here's what it compiles to:
  1020.  
  1021.  (1)  MOVEA.L    $0008(A6),A0
  1022.  (2)  MOVEA.L    (A0),A0
  1023.  (3)  MOVE.L     (A0),D7
  1024.  
  1025. If your interrupt fires between instructions (2) and (3) and allocates
  1026. a handle (or moves the heap in any way), you will have invalidated the
  1027. pointer in A0, which is a pointer into an unlocked block.  This is only
  1028. the first example; hundreds of programs use pointers into unlocked
  1029. blocks for long stretches of code, as long as they know they do not
  1030. call any routines that might cause the movement of the block in
  1031. question.  As far as I can tell, there is no way to determine at time
  1032. X whether any such pointers exist.  Thus, the only time memory can
  1033. be allocated from any shared heap (application, system or process
  1034. manager) is when a call which might move that heap is called.  Thus,
  1035. as far as I can tell, your scheme is unworkable, unless it relies
  1036. upon only getting control at appropriate times or using a heap which
  1037. is unused by any other process.
  1038.  
  1039. Tim Dierks
  1040. MacDTS, but I geek with my knees
  1041.  
  1042. +++++++++++++++++++++++++++
  1043.  
  1044. From: Jeff E Mandel <mandel@tmc.tulane.edu>
  1045. Organization: Tulane University School of Medicine
  1046. Date: Wed, 28 Oct 1992 14:56:44 GMT
  1047.  
  1048. In article <werner-271092123531@128.32.157.31> John Werner,
  1049. werner@soe.berkeley.edu writes:
  1050. >YES.  Some code (probably including many toolbox traps) may have
  1051. >dereferenced a handle into a pointer, and your NewHandle call might move
  1052. >the block out from under the pointer.
  1053.  
  1054. In article <absurd-271092125416@seuss.apple.com> Tim Dierks,
  1055. absurd@apple.apple.com writes:
  1056. >The real sticking point is, as I see it,
  1057. >that virtually all Mac programs and the toolbox rely on memory not
  1058. >moving or being purged except at well-defined times.
  1059. [...]
  1060. > Thus, the only time memory can
  1061. >be allocated from any shared heap (application, system or process
  1062. >manager) is when a call which might move that heap is called.
  1063.  
  1064. Well, obviously correct. Since there is no way to guard everything that
  1065. dereferences a handle, the idea of delivering the task immediately if the
  1066. semaphore is zero won't work. On the other hand, servicing the queue on
  1067. exit from (or entrance to) the memory manager should not create the
  1068. problem, because after a memory  manager call any dereferenced handle
  1069. should be presumed invalid.
  1070.  
  1071. Since memory manager calls are fairly ubiquitous, there are very few
  1072. operations that a foreground application might be involved in which would
  1073. freeze out the queue servicing for very long. One is a tight calculation
  1074. loop, for which I can see no recourse; the other is a synchronous read
  1075. operation, where you sit in a loop polling ioStatus. I suppose you could
  1076. patch PBRead, but it isn't a trivial patch. In any event, it may not be
  1077. worth worrying about. My experience is that synchronous reads either
  1078. complete, time out in a reasonble amount of time, or hang the machine.
  1079.  
  1080. To make life easier for the application programmer trying to size the
  1081. (small) static buffer that would be necessary to avoid losing data while
  1082. waiting for the queue to be serviced, the queue service routine could
  1083. keep track of the interval between calls and update a count (available by
  1084. Gestalt) which would be the longest delay in the queue servicing.
  1085.  
  1086. So, having amended the proposal to eliminate immediate delivery, does
  1087. anyone else see any problem with having a queue which is serviced when
  1088. the patched memory manager traps are called?
  1089.  
  1090. Jeff E Mandel MD MS
  1091. Associate Professor of Anesthesiology
  1092. Tulane University School of Medicine
  1093. New Orleans, LA
  1094.  
  1095. mandel@vax.anes.tulane.edu
  1096.  
  1097. ---------------------------
  1098.  
  1099. From: yjc@po.cwru.edu (Jerome Chan)
  1100. Subject: How to tell if App is in Background?
  1101. Date: 24 Oct 92 14:38:36 GMT
  1102. Organization: The Tofu Society of Singapore
  1103.  
  1104. How do you tell if an App is in the background? I seem to recall that it is
  1105. possible to launch an application in the background under system 7.x.
  1106.  
  1107. - ---
  1108.  The Evil Tofu
  1109.  
  1110. +++++++++++++++++++++++++++
  1111.  
  1112. From: d88-jwa@hemul.nada.kth.se (Jon Wtte)
  1113. Date: 24 Oct 92 15:59:22 GMT
  1114. Organization: Royal Institute of Technology, Stockholm, Sweden
  1115.  
  1116. > yjc@po.cwru.edu (Jerome Chan) writes:
  1117.  
  1118.    How do you tell if an App is in the background? I seem to recall that it is
  1119.    possible to launch an application in the background under system 7.x.
  1120.  
  1121. Well:
  1122.  
  1123. 1) You could assume you're in front at launch, and listen in on
  1124.    the osEvents that come.
  1125.  
  1126. 2) You could use GetFrontProcess and call SameProcess with the
  1127.    result of GetCurrentProcess.
  1128.  
  1129. 3) Background-only apps never are in the front.
  1130.  
  1131. - -- 
  1132.  -- Jon W{tte, h+@nada.kth.se, Mac Hacker Suedoise (not french speaking) --
  1133.   _/~|   Yellow
  1134.  / * \_  Shark                      (This signature has won the "Worst ASCII
  1135.  ~~~~\/  Software                    Logo of the Year" award)
  1136.  
  1137. +++++++++++++++++++++++++++
  1138.  
  1139. From: keith@taligent.com (Keith Rollin)
  1140. Date: 26 Oct 92 00:38:09 GMT
  1141. Organization: Taligent
  1142.  
  1143. In article <D88-JWA.92Oct24165922@hemul.nada.kth.se>,
  1144. d88-jwa@hemul.nada.kth.se (Jon Wtte) wrote:
  1145. > > yjc@po.cwru.edu (Jerome Chan) writes:
  1146. >    How do you tell if an App is in the background? I seem to recall that it is
  1147. >    possible to launch an application in the background under system 7.x.
  1148. > Well:
  1149. > 1) You could assume you're in front at launch, and listen in on
  1150. >    the osEvents that come.
  1151. > 2) You could use GetFrontProcess and call SameProcess with the
  1152. >    result of GetCurrentProcess.
  1153. > 3) Background-only apps never are in the front.
  1154.  
  1155. Re 1): I think that all applications are initially launched into the
  1156. background, and that you should look for "resume" events before acting like
  1157. you are in the foreground. This is related to the "call WaitNextEvent three
  1158. times" trick before showing your application's splash screen.
  1159.  
  1160. - -----
  1161. Keith Rollin
  1162. Phantom Programmer
  1163. Taligent, Inc.
  1164.  
  1165. ---------------------------
  1166.  
  1167. From: chrisv@runx.oz.au (Chris Velevitch)
  1168. Subject: Newton Development
  1169. Date: 16 Oct 92 13:38:12 GMT
  1170. Organization: RUNX Un*x Timeshare.  Sydney, Australia.
  1171.  
  1172.  
  1173. I want to develop applications for the Newton, but I would like
  1174. more information on what is involved.
  1175.  
  1176. What is the development language/environment?
  1177. What are the Design and interface guidelines?
  1178. What type of non-volatile storage and capacity?
  1179.  
  1180.  
  1181. Chris
  1182.  
  1183. - -- 
  1184. Chris Velevitch, Soft, Inc.
  1185. chrisv@runxtsa.runx.oz.au
  1186.  
  1187. +++++++++++++++++++++++++++
  1188.  
  1189. From: howard@netcom.com (Howard Berkey)
  1190. Organization: Netcom - Online Communication Services  (408 241-9760 guest) 
  1191. Date: Sat, 17 Oct 1992 02:53:38 GMT
  1192.  
  1193. In article <1992Oct16.133812.28157@runx.oz.au> chrisv@runx.oz.au (Chris Velevitch) writes:
  1194. >
  1195. >I want to develop applications for the Newton, but I would like
  1196. >more information on what is involved.
  1197. >
  1198. >What is the development language/environment?
  1199. >What are the Design and interface guidelines?
  1200. >What type of non-volatile storage and capacity?
  1201. >
  1202. >
  1203. >Chris
  1204.  
  1205. Check comp.sys.vaporware and comp.get.competitors.to.spend.big.RandD.bucks
  1206. :-)
  1207.  
  1208. - -Howard
  1209. - -- 
  1210. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1211. Howard Berkey                        howard@netcom.com
  1212. Do what keeps thou from wilting shall be the loophole in the law.
  1213.  
  1214.  
  1215.  
  1216. +++++++++++++++++++++++++++
  1217.  
  1218. From: David_B._Lamkins@fourd.com
  1219. Organization: 4th Dimension BBS
  1220. Date: Sun, 25 Oct 1992 19:03:16 EST
  1221.  
  1222. > I want to develop applications for the Newton, but I would like
  1223. > more information on what is involved.
  1224. > What is the development language/environment?
  1225. > What are the Design and interface guidelines?
  1226. > What type of non-volatile storage and capacity?
  1227. > Chris
  1228. > -- 
  1229. > Chris Velevitch, Soft, Inc.
  1230. > chrisv@runxtsa.runx.oz.au
  1231.  
  1232. If you believe that Dylan is the language in which you'll be developing Newton
  1233. apps (I've seen conflicting stories in MacWeek, but most of them cite Dylan as
  1234. Newton's "native" language), then you can get a start by learning about Dylan.
  1235.  
  1236. There is a mailing list for Dylan: info-dylan@cambridge.apple.com, requests
  1237. for subscription should be addressed to info-dylan-request@cambridge.apple.com.
  1238. Because of the high volume of traffic on this mailing list, there is a move
  1239. afoot to start a Dylan newsgroup.
  1240.  
  1241. You can also get a copy of the Dylan language manual by writing to Apple
  1242. Computer, 1 Main St., Cambridge, MA 02142 USA, or by calling them at
  1243. 617-374-5300.
  1244.  
  1245. Dave
  1246.  
  1247. ********************************************************************
  1248. System: fourd.com                                Phone: 617-494-0565
  1249. Cute quote:  Being a computer means never having to say you're sorry
  1250. ********************************************************************
  1251.  
  1252.  
  1253. ---------------------------
  1254.  
  1255. From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
  1256. Subject: Watch out for QDError
  1257. Date: 25 Oct 92 20:10:43 GMT
  1258. Organization: Kalamazoo College
  1259.  
  1260. This is a "don't do the same stupid thing I did" article.  I put a
  1261. call to _QDError in a program that would be used on Classic
  1262. QuickDraw machines.  "Hey, I'm publishing this source code," I
  1263. thought, "I'll be a good doobie and check for all possible
  1264. errors."  That innocuous-looking trap is, I believe, for Color QD
  1265. machines only.  Oh, by the way, it works fine on a System 7 SE,
  1266. so make that Color-QD-or-System-7 machines.
  1267.  
  1268. However (and this may be a bug in the system)--when running
  1269. System 6 on a Plus, it looks like a call to QDError works
  1270. _except_ that it tries to write a long where a short belongs. 
  1271. This produced a pretty spectacular and hard-to-find crash.  It
  1272. just happened to overwrite the hi word of my A6 link with
  1273. zero--and the program went on to do lots of computation, and even
  1274. RTS'd OK, but the parent function had a screwed-up A6 after that.
  1275. Bad news.
  1276.  
  1277. Might anyone know whether this is a bug in the system?  Or is it
  1278. getting some other trap instead of _QDError, that fortuitously
  1279. just happens not to blow up the computer?
  1280.  
  1281. In any event--don't call QDError() unless you're running Color
  1282. QuickDraw.
  1283. - -- 
  1284.  Jamie McCarthy      Internet: k044477@kzoo.edu      AppleLink: j.mccarthy
  1285.  I suppose ya don't think I was run over by a streetcar!
  1286.  
  1287. +++++++++++++++++++++++++++
  1288.  
  1289. From: keith@taligent.com (Keith Rollin)
  1290. Date: 26 Oct 92 00:54:39 GMT
  1291. Organization: Taligent
  1292.  
  1293. In article <1992Oct25.201043.14736@hobbes.kzoo.edu>,
  1294. k044477@hobbes.kzoo.edu (Jamie R. McCarthy) wrote:
  1295. > This is a "don't do the same stupid thing I did" article.  I put a
  1296. > call to _QDError in a program that would be used on Classic
  1297. > QuickDraw machines.  "Hey, I'm publishing this source code," I
  1298. > thought, "I'll be a good doobie and check for all possible
  1299. > errors."  That innocuous-looking trap is, I believe, for Color QD
  1300. > machines only.  Oh, by the way, it works fine on a System 7 SE,
  1301. > so make that Color-QD-or-System-7 machines.
  1302. >  
  1303. > However (and this may be a bug in the system)--when running
  1304. > System 6 on a Plus, it looks like a call to QDError works
  1305. > _except_ that it tries to write a long where a short belongs. 
  1306. > This produced a pretty spectacular and hard-to-find crash.  It
  1307. > just happened to overwrite the hi word of my A6 link with
  1308. > zero--and the program went on to do lots of computation, and even
  1309. > RTS'd OK, but the parent function had a screwed-up A6 after that.
  1310. > Bad news.
  1311. >  
  1312. > Might anyone know whether this is a bug in the system?  Or is it
  1313. > getting some other trap instead of _QDError, that fortuitously
  1314. > just happens not to blow up the computer?
  1315.  
  1316. I think that calls to _QDError (trap AA40) wrap around and end up going to
  1317. _FixToLong (trap A840) on Macs with the smaller toolbox trap table. This
  1318. should be true of any trap number above A9FF on such Macs. It's because of
  1319. this wraparound that the published TrapAvailable routines check the size of
  1320. the trap table.
  1321.  
  1322. - -----
  1323. Keith Rollin
  1324. Phantom Programmer
  1325. Taligent, Inc.
  1326.  
  1327. ---------------------------
  1328.  
  1329. From: jess@gn.ecn.purdue.edu (Jess M Holle)
  1330. Subject: MPW C++ 3.1, does it work with MPW 3.2??
  1331. Date: 23 Oct 92 18:21:08 GMT
  1332. Organization: Purdue University Engineering Computer Network
  1333.  
  1334. I have MPW 3.2 shell, C compiler, the corresponding version of SADE,
  1335. etc. available to me AND MPW C++ 3.1.  Will this combination work??
  1336. What changed from MPW C++ 3.1 to MPW C++ 3.2?
  1337.  
  1338. Thanks,
  1339. Jess Holle
  1340.  
  1341. P.S.  I used to be up to date on all of the MPW stuff, but since using 
  1342. Think C for all of my work for a while, I don't really remember much about
  1343. MPW and its various version details.
  1344.  
  1345. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1346. - ---Hoping for Think C++ (plus compiler warnings, plus backgroundable 
  1347.                          compiles, plus...)
  1348. - ---Hoping for a compact, fast, easy-to-use, affordably-upgradeable MPW
  1349. - ---I will not despair, I will not despair,... (or so I keep telling myself)
  1350. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1351.  
  1352. +++++++++++++++++++++++++++
  1353.  
  1354. From: ksand@apple.com (Kent Sandvik)
  1355. Date: 26 Oct 92 06:44:43 GMT
  1356. Organization: Apple
  1357.  
  1358. In article <1992Oct23.182108.28293@gn.ecn.purdue.edu>,
  1359. jess@gn.ecn.purdue.edu (Jess M Holle) wrote:
  1360. > I have MPW 3.2 shell, C compiler, the corresponding version of SADE,
  1361. > etc. available to me AND MPW C++ 3.1.  Will this combination work??
  1362. > What changed from MPW C++ 3.1 to MPW C++ 3.2?
  1363.  
  1364. Well, it's officially unsupported, but that does not mean that it
  1365. does not work. As I know MPW C++ 3.1 works fine with MPW 3.2. The
  1366. biggest delta between C++ 3.1 and 3.2 is that 3.1 was based on
  1367. Cfront 2.0, while MPW C++ 3.2 is based on Cfront 2.1. In addition
  1368. we fixed Apple extension bugs. Note that MacApp 3.0(.1) is tested
  1369. and verified using MPW C++ 3.2, so you might have sporadic and unknown
  1370. problems with MPW C++ 3.1.
  1371.  
  1372. Kent
  1373. - -------------------
  1374. Kent Sandvik (UUCP: ....!apple!ksand; INTERNET: ksand@apple.com)
  1375. DISCLAIMER: Private activities on the Net.
  1376.  
  1377. ---------------------------
  1378.  
  1379. From: kim@acmehi.microware.com (Kim Kempf)
  1380. Subject: PBResolveFileIDRef() trouble
  1381. Date: 23 Oct 92 19:42:34 GMT
  1382. Organization: Acme Hitech Systems, Inc., Johnston, Ia.
  1383.  
  1384. I have a file ID and volume reference number.  I need to take this file ID
  1385. and (if found) get the parent directory and name.  PBResolveFileIDRef()
  1386. seems to be the likely function to use.  I know I'm setting up something
  1387. wrong because it always returns either -35 (nsvErr) or -1300 (fidNotFoundErr).
  1388. Does anyone have an example code segment that uses this function correctly?
  1389. Thanks in advance.
  1390.  
  1391. Think C 5.0:
  1392.  
  1393. #include <stdio.h>
  1394. #include <Files.h>
  1395.  
  1396. Str255 temp;
  1397.  
  1398. main()
  1399. {
  1400.     HParamBlockRec hpb;
  1401.     OSErr err;
  1402.  
  1403.     hbp.fidParam.ioNameptr = temp;
  1404.     hbp.fidParam.ioFileID = 676;       // this file ID is known to exist
  1405.     hbp.filParam.ioVRefNum = -1;       // assume boot volume (maybe wrong?)
  1406.  
  1407.     if ((err = PBResolveFileIDRef(&hpb, FALSE)) == noErr)
  1408.         printf("Filename = '%#s'\n", hpb.fidParam.ioNamePtr);
  1409.     else printf("%d\n", err);
  1410.  
  1411.     exit(0);
  1412. }
  1413.  
  1414. - -- 
  1415. - ----------------
  1416. Kim Kempf, Acme Hitech Systems, Inc.          uunet!mcrware!acmehi!kim
  1417. Johnston, IA 50131-1551
  1418. Tel/Fax: (515) 253-0057
  1419.  
  1420. +++++++++++++++++++++++++++
  1421.  
  1422. From: absurd@apple.apple.com (Tim Dierks, software saboteur)
  1423. Date: Mon, 26 Oct 1992 17:05:51 GMT
  1424. Organization: MacDTS Marauders
  1425.  
  1426. In article <1310@acmehi.UUCP>, kim@acmehi.microware.com (Kim Kempf) wrote:
  1427. > I have a file ID and volume reference number.  I need to take this file ID
  1428. > and (if found) get the parent directory and name.  PBResolveFileIDRef()
  1429. > seems to be the likely function to use.  I know I'm setting up something
  1430. > wrong because it always returns either -35 (nsvErr) or -1300 (fidNotFoundErr).
  1431. > Does anyone have an example code segment that uses this function correctly?
  1432. > Thanks in advance.
  1433. > Think C 5.0:
  1434. > #include <stdio.h>
  1435. > #include <Files.h>
  1436. > Str255 temp;
  1437. > main()
  1438. > {
  1439. >     HParamBlockRec hpb;
  1440. >     OSErr err;
  1441. >     hbp.fidParam.ioNameptr = temp;
  1442. >     hbp.fidParam.ioFileID = 676;       // this file ID is known to exist
  1443. >     hbp.filParam.ioVRefNum = -1;       // assume boot volume (maybe wrong?)
  1444. >     if ((err = PBResolveFileIDRef(&hpb, FALSE)) == noErr)
  1445. >         printf("Filename = '%#s'\n", hpb.fidParam.ioNamePtr);
  1446. >     else printf("%d\n", err);
  1447. >     exit(0);
  1448. > }
  1449.  
  1450. The PBResolveFileIDRef function takes the ioNamePtr field as an input
  1451. giving the name of the volume you want to look in.  To make sure you're
  1452. not confusing it, you should set that string to a null string before
  1453. calling the routine, or give it a real volume name.  Try this:
  1454.  
  1455. OSErr
  1456. MakeFSSpecFromFileID(short vRefNum,long fileID,FSSpec *fsp)
  1457. {   OSErr               err;
  1458.     HParamBlockRec      hpb;
  1459.     char                name[32];
  1460.     
  1461.     // Specify file by vRefNum + file ID; this requires ioNamePtr to be NIL
  1462. or
  1463.     //  point to a non-volume name (the empty string is safest).
  1464.     
  1465.     name[0] = '\0';     // Zero out name
  1466.     
  1467.     hpb.fidParam.ioNamePtr = (StringPtr)name;
  1468.     hpb.fidParam.ioVRefNum = vRefNum;
  1469.     hpb.fidParam.ioFileID = fileID;
  1470.     
  1471.     err = PBResolveFileIDSync(&hpb);
  1472.     if (err)
  1473.         return err;
  1474.     
  1475.     err = FSMakeFSSpec(vRefNum,hpb.fidParam.ioSrcDirID,
  1476.                          (StringPtr) name,fsp);
  1477.     
  1478.     return err;
  1479. }
  1480.  
  1481. ** Note: this is sort of off of the top of my head; I'm pretty sure it
  1482. works, but I'm not certain.
  1483.  
  1484. Tim Dierks
  1485. MacDTS is only skin deep, but geek goes straight to the bone.
  1486.  
  1487. ---------------------------
  1488.  
  1489. From: siegel@world.std.com (Rich Siegel)
  1490. Subject: Help! CTB's NuLookup() call crashing...
  1491. Date: 27 Oct 92 18:36:37 GMT
  1492. Organization: GCC Technologies
  1493.  
  1494. I'm trying to use the NuLookup() routine for choosing LaserWriters on
  1495. the net. Sometimes it works, but usually it just crashes with an illegal
  1496. instruction exception, because somewhere deep inside the CTB, someone
  1497. is jumping to location zero.
  1498.  
  1499. Here's the setup and the call:
  1500.  
  1501.         NBPReply reply;
  1502.         NLType types;
  1503.  
  1504.         OSErr result;
  1505.  
  1506.         Point pt = {90, 90};
  1507.  
  1508.         types[0].hIcon = GetResource('SICN', 128);
  1509.         CopyStr("\pLaserWriter", types[0].typeStr);
  1510.  
  1511.         if (NuLookup(pt, "\pAvailable Printers:", 1, types, nil, nil, nil, &rep)
  1512.                 return userCanceledErr;
  1513.  
  1514. Am I doing something egregiously ignorant, or is there something subtle I
  1515. need to do to get this to work?
  1516.  
  1517. As a side issue, how do I center the NuLookup dialog? Passing
  1518. {0, 0} or {-1, -1} doesn't work - the dialog gets stuffed in the upper
  1519. left corner of the screen - and the dialog ID of the dialog isn't
  1520. published...
  1521.  
  1522. Thanks in advance for any assistance.
  1523.  
  1524. R.
  1525.  
  1526. - -- 
  1527. - -----------------------------------------------------------------------
  1528. Rich Siegel                              Internet: siegel@world.std.com
  1529. Software Engineer & Toolsmith
  1530. GCC Technologies
  1531.  
  1532. +++++++++++++++++++++++++++
  1533.  
  1534. From: leonardr@netcom.com (Leonard Rosenthol)
  1535. Date: 28 Oct 92 00:50:47 GMT
  1536. Organization: Netcom - Online Communication Services  (408 241-9760 guest)
  1537.  
  1538. In article <BwsMD2.ELz@world.std.com> siegel@world.std.com (Rich Siegel) writes:
  1539. >I'm trying to use the NuLookup() routine for choosing LaserWriters on
  1540. >the net. Sometimes it works, but usually it just crashes with an illegal
  1541. >instruction exception, because somewhere deep inside the CTB, someone
  1542. >is jumping to location zero.
  1543. >
  1544.     Welcome to the most common bug in using NuLookup!
  1545.  
  1546. >Here's the setup and the call:
  1547. >
  1548. >        NBPReply reply;
  1549. >        NLType types;
  1550. >
  1551. >        Point pt = {90, 90};
  1552. >
  1553. >        if (NuLookup(pt, "\pAvailable Printers:", 1, types, nil, nil, nil, &rep)
  1554. >Am I doing something egregiously ignorant, or is there something subtle I
  1555. >need to do to get this to work?
  1556. >
  1557.     You are NOT initializing the NBPReply record.  NuLookup uses the
  1558. contents of the NBPReply to allow you to "prechoose" an entry to be hilited
  1559. when the dialog comes up.  However, it doesn't sanity check and the 
  1560. "preflighting" feature is not documented.
  1561.  
  1562. >As a side issue, how do I center the NuLookup dialog? Passing
  1563. >{0, 0} or {-1, -1} doesn't work - the dialog gets stuffed in the upper
  1564. >left corner of the screen - and the dialog ID of the dialog isn't
  1565. >published...
  1566. >
  1567.     You don't :(.  You either have to use NuPLookup and attempt to center
  1568. during the init call of the filterProc or guess...
  1569.  
  1570.  
  1571. - -- 
  1572. - -----------------------------------------------------------------------------
  1573. Leonard Rosenthol            Internet:     leonardr@netcom.com
  1574. Director of Advanced Technology        AppleLink:    MACgician
  1575. Aladdin Systems, Inc.            GEnie:        MACgician
  1576.  
  1577. ---------------------------
  1578.  
  1579. End of C.S.M.P. Digest
  1580. **********************
  1581.